<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\ReportSetting;
use Carbon\Carbon;
use DB;
use Illuminate\Http\Request;

class StatisticController extends Controller
{

    use \App\Http\Traits\UserPrivilege;

    protected $message = [
        'typeid.required' => '设备分类不能为空',
        'pdi_index.required' => '设备不能为空',
        'selectDate.required' => '请选择查询时间',
        'selectDate.in' => '查询时间分类非法',
        'rd_updatetime.required_if' => '自定义时间不能为空',
        'rd_updatetime.*.date_format' => '自定义时间格式不正确',
    ];

    public function index(Request $request)
    {
        $cid = $request->input('company');
        $sid = $request->input('site');

        $pdi = $request->input('pdi_index', 0);

        $this->validate($request, [
            'typeid' => 'required',
            'pdi_index' => 'required',
            'selectDate' => 'required|in:day,week,month,year,custom',
            'rd_updatetime' => 'required_if:selectDate,custom',
            'rd_updatetime.*' => 'date_format:Y-m-d H:i:s',
        ], $this->message);

        //    $deviceInfo = PriDeviceInfo::select(['pdi_index'])->company($cid)->site($sid)->first();

        //    if(!$deviceInfo) {
        //        $this->error('设备不存在!');
        //    }

        $dtType = $request->input('typeid', 0);

        if (empty($dtType)) {
            return $this->error('设备类型不存在');
        }

        $config = ReportSetting::where('device_type', $dtType)->first();

        if (!$config) {
            return $this->error('数据表不存在');
        }

        $table = $config->report_table_name;

        $configField = $config->settingField()->select(['sum_field as prop', 'sum_desc as label'])
        ->get()
        ->map(function($item){
            $item->prop = 'hd_'.$item->prop;
            $item->label = preg_replace('/\d+$/', '', $item->label);
            return $item;
        })
        ->toArray();

        $betweenTime = $this->getTime($request);

        $query = DB::table($table);

        if ($betweenTime) {
            $query->whereBetween('hd_datetime', $betweenTime);
        }

        $searchType = $this->getSearchType($request);

        list($group, $fields, $columns, $labels) = $this->getFields($configField, $searchType);
        $query
            ->where('pdi_index', '=', $pdi)
            ->select($fields);
        if ($group) {
            $query->groupBy($group);
        }

        $device = $query->get();
        $result = [];
        if ($device) {
            $result = $this->format($device, $columns);
        }
        $result['searchType'] = $searchType;

        return ['data' => $result, 'labels' => $labels];
    }

    /**
     * 返回表字段类型
     * @param int $typeId
     * @return array
     */
    protected function getFields($params, $searchType = 'hour', $prefix = 'hd_', $dateField = 'hd_datetime')
    {

        $labels = array_merge([$dateField => "日期"], array_column($params, 'label', 'prop'));

        $columns = array_keys($labels);

        $fields = [];
        foreach ($params as $param) {
            $field = array_get($param, 'prop');
            $fields[] = $searchType == 'hour' ? "$field" : DB::raw("round(sum($field)/count($field),2) as $field");
        }

        $group = '';
        switch ($searchType) {
            case 'hour':
                $group = '';
                $fields[] = $dateField;
                break;
            case 'day':
                $group = DB::raw("date_format($dateField, '%Y-%m-%d')");
                $fields[] = DB::raw($group . ' as ' . $dateField);
                break;
            case 'month':
                $group = DB::raw("date_format($dateField, '%Y-%m')");
                $fields[] = DB::raw($group . ' as ' . $dateField);
                break;
            default:
                $group = '';
                $fields[] = $dateField;
                break;
        }
        return [$group, $fields, $columns, $labels];
    }

    /**
     * 格式化历史数据
     * @param array $data
     * @param string $table
     * @return array
     */
    protected function format($data, $columns)
    {
        $result = [
            "columns" => $columns,
            "rows" => $data,
        ];
        return $result;
    }

    /**
     * 获取时间范围
     * @param Request $request
     * @return array
     */
    protected function getTime(Request $request)
    {
        $seldate = $request->input('selectDate');
        $zhStart = Carbon::now();
        $zhEnd = Carbon::now();
        $date = [];
        switch ($seldate) {
            case 'day':
                $date = [$zhStart->startOfDay()->toDateTimeString(), $zhEnd->endOfDay()->toDateTimeString()];
                break;
            case 'week':
                $start = $zhStart->startOfWeek(Carbon::MONDAY);
                $end = $zhEnd->endOfWeek(Carbon::SUNDAY);
                $date = [$start->toDateTimeString(), $end->toDateTimeString()];
                break;
            case 'month':
                $date = [$zhStart->startOfMonth()->toDateTimeString(), $zhEnd->endOfMonth()->toDateTimeString()];
                break;
            case 'year':
                $date = [$zhStart->startOfYear()->toDateTimeString(), $zhEnd->endOfYear()->toDateTimeString()];
                break;
            case 'custom':
                $sdate = $request->input('rd_updatetime');
                $zhStart = Carbon::parse($sdate[0]);
                $zhEnd = Carbon::parse($sdate[1]);
                $date = [$zhStart->toDateTimeString(), $zhEnd->toDateTimeString()];
                break;
            default:
                break;
        }
        return $date;
    }

    //获取查询方式
    private function getSearchType($request)
    {
        $seldate = $request->input('selectDate');

        $searchType = 'hour';

        switch ($seldate) {
            case 'day':
                $searchType = 'hour';
                break;
            case 'week':
            case 'month':
                $searchType = 'day';
                break;
            case 'year':
                $searchType = 'month';
                break;
            case 'custom':
                $searchType = $this->getSearchCustom($request);
                break;
            default:
                break;
        }
        return $searchType;

    }

    //获取自定义时间查询
    private function getSearchCustom($request)
    {
        $searchType = 'hour';
        $sdate = $request->input('rd_updatetime');
        $zhStart = Carbon::parse($sdate[0]);
        $zhEnd = Carbon::parse($sdate[1]);
        $days = $zhEnd->diffInDays($zhStart);
        if ($days < 1) {
            $searchType = 'hour';
        } elseif ($days >= 1 && $days <= 31) {
            $searchType = 'day';
        } elseif ($days > 31) {
            $searchType = 'month';
        }
        return $searchType;
    }
}
